package com.data4.feignapi.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;


@Component
public class JwtUtils {


    private final String secret = "LQhLXsrYbZ520";

    private final long expiration = 18000000L;//密钥


    /**
     * 生成token令牌，加密
     *
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return token
     * 下方subject 是 JWT 中一个重要的声明字段，表示该 JWT 代表的主体。它可以帮助你快速识别 JWT 的持有者。
     */

    public String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setId(Claims.ID)//设置jti(JWT ID)：是JWT的唯一标识，
                // 根据业务需要，这个可以设置为一个不重复的值，主要用来作为令牌的唯一标识。
                .setIssuedAt(new Date())//设置签发时间
                .addClaims(claims)//设置负载
                .signWith(SignatureAlgorithm.HS256, secret)//设置签名算法
                .setExpiration(new Date(System.currentTimeMillis() + expiration))//设置令牌过期时间
                .compact();//生成令牌
    }

    /**
     * 解析token令牌得到负载，解密
     *
     * @param token token令牌
     * @return 负载
     */
    private Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 验证token令牌，进行token校验
     *
     * @param token 令牌
     * @return 是否有效
     */
    public Claims validateAndParseToken(String token) {
        try {

            return parseToken(token);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 刷新Token
     *
     * @param token 旧的Token令牌
     * @return 新的Token令牌
     */
    public String refreshToken(String token) {
        try {
            // 解析旧的Token，获取负载信息
            Claims claims = parseToken(token);
            // 生成新的Token，设置过期时间和签名算法等参数
            return generateToken(claims);
        } catch (Exception e) {
            throw new RuntimeException("无法刷新令牌！", e);
        }
    }

}